//
// Created by xbm on 23-3-10.
//

#ifndef WEBSERVER_EVENT_H
#define WEBSERVER_EVENT_H

#include <string>
#include <memory>
#include <functional>
#include <utility>
#include <chrono>
#include <unordered_map>
#include "../util/concurrentMap.h"
#include "../socket/socketClient.h"
#include "../timer/timer.h"

namespace event {

union Event_Type {
    struct Type {
        int16_t major;
        int16_t minor;
    };
    Type type;
    int num;
};


struct Event {
    Event_Type type;
};

struct SocketEvent : Event {
    static constexpr int16_t MAJOR_TYPE = 1;
    static constexpr int16_t ACCEPT = 1 << 1;
    static constexpr int16_t READ = 1 << 2;
    static constexpr int16_t WRITE = 1 << 3;
    static constexpr int16_t ERROR = 1 << 4;
    static constexpr int16_t CLOSE = 1 << 5;
    static constexpr int16_t EXPIRE = 1 << 6;
    static constexpr auto EXPIRE_TIME = 1h;
    struct Status {
        chrono::time_point<chrono::high_resolution_clock> timestamp;
        socket_epoll::SocketClient socketClient;
        string buffer;
    };

    int fd = -1;
    static inline ConcurrentMap<int, Status> fd2status;

    static shared_ptr<SocketEvent> make_event(int fd, int16_t minor_type) {
        return make_shared<SocketEvent>(SocketEvent{{MAJOR_TYPE, minor_type}, fd});
    }
};

struct RunSelfEvent : Event {
    static constexpr int16_t MAJOR_TYPE = 2;

    std::function<void()> runner;

    static shared_ptr<RunSelfEvent> make_event(std::function<void()> &&runner) {
        return make_shared<RunSelfEvent>(RunSelfEvent{{MAJOR_TYPE, 0}, std::move(runner)});
    }
};


}
#endif //WEBSERVER_EVENT_H
